home *** CD-ROM | disk | FTP | other *** search
/ Language/OS - Multiplatform Resource Library / LANGUAGE OS.iso / p4 / p4-1_2c.lha / p4-1.2c / lib / p4_broadcast.c < prev    next >
C/C++ Source or Header  |  1993-05-25  |  11KB  |  557 lines

  1. #include "p4.h"
  2. #include "p4_sys.h"
  3.  
  4. #define MAXVAL(a,b) (((a)>(b)) ? (a) : (b))
  5. #define MINVAL(a,b) (((a)<(b)) ? (a) : (b))
  6. #define ABSVAL(a)   (((a)>=0 ) ? (a) : -(a))
  7.  
  8. static P4VOID init_p4_brdcst_info();
  9.  
  10. int p4_broadcastx(type, data, data_len, data_type)
  11. int type;
  12. char *data;
  13. int data_len, data_type;
  14. /*
  15.   Broadcast my data to all other processes.
  16.   Other processes call p4_recv() in the normal fashion, specifying
  17.   the node (if desired) that originated the broadcast.
  18. */
  19. {
  20.     int status = 0;
  21.     struct p4_msg *tmsg;
  22.  
  23. #if defined(NCUBE)
  24.     int req_type, req_from;
  25.  
  26.     status = send_message(type, p4_get_my_id(), 0xffff, data, data_len,
  27.                   data_type, FALSE, FALSE);
  28.     req_type = type;
  29.     req_from = p4_get_my_id();
  30.     tmsg = recv_message(req_type,req_from); /* ncube broadcast comes back */
  31.     free_p4_msg(tmsg);        /* throw it away */
  32.     return(status);
  33. #endif
  34.  
  35.     init_p4_brdcst_info();
  36.  
  37.     /* Build the message with broadcast bit set */
  38.  
  39.     if (p4_get_my_id())
  40.     {                /* Not node 0 */
  41.     /*
  42.      * Send data to node 0. Recv internally discards broadcast message
  43.      * that is from the same process
  44.      */
  45.  
  46.     status = send_message(type, p4_get_my_id(), 0, data, data_len,
  47.                   data_type, P4_BROADCAST_MASK, FALSE);
  48.     }
  49.     else
  50.     {
  51.     /* I'm top of the tree ... start broadcast proper */
  52.  
  53.     status = subtree_broadcast_p4(type, p4_get_my_id(), data, data_len, data_type);
  54.     }
  55.  
  56.     if (status && !(SOFTERR))
  57.     p4_error("p4_broadcast failed, type=", type);
  58.  
  59.     return status;
  60. }
  61.  
  62. int subtree_broadcast_p4(type, from, data, data_len, data_type)
  63. char *data;
  64. int type, from, data_len, data_type;
  65. /*
  66.   Broadcast message to processes in my subtree.
  67.  
  68.   1) Send to left/right remote cluster masters
  69.   2) Send to left/right local  cluster slaves
  70. */
  71. {
  72.     int status = 0;
  73.     int size;
  74.     int nodes[4], i;
  75.     struct p4_msg *tmsg;
  76.  
  77.     init_p4_brdcst_info();
  78.  
  79.     p4_dprintfl(90, "subtree_broadcast_p4: type=%d, len=%d\n", type, data_len);
  80.  
  81.     nodes[0] = p4_brdcst_info.left_cluster;
  82.     nodes[1] = p4_brdcst_info.right_cluster;
  83.     nodes[2] = p4_brdcst_info.left_slave;
  84.     nodes[3] = p4_brdcst_info.right_slave;
  85.  
  86.     for (i = 0; i < 4; i++)
  87.     {
  88.     if (nodes[i] > 0)
  89.     {
  90.         if (send_message(type, from, nodes[i], data, data_len,
  91.                  data_type, P4_BROADCAST_MASK, FALSE))
  92.         {
  93.         status = -1;
  94.         break;
  95.         }
  96.     }
  97.     }
  98.  
  99.     if (status && !SOFTERR)
  100.     p4_error("subtree_broadcast_p4 failed, type=", tmsg->type);
  101.  
  102.     p4_dprintfl(90, "subtree_broadcast_p4: exit status=%d\n", status);
  103.     return status;
  104. }
  105.  
  106. static P4VOID init_p4_brdcst_info()
  107. /*
  108.   Construct tree connections for cluster-master and slave
  109.   processes and insert into global structure
  110. */
  111. {
  112. #define MAX_MASTERS P4_MAXPROCS
  113.     int me, my_master, node, n_master, indx = (-1);
  114.     int master_list[MAX_MASTERS], previous_id;
  115.  
  116.     if (p4_brdcst_info.initialized)    /* Only need to do this once */
  117.     return;
  118.  
  119.     p4_brdcst_info.initialized = 1;
  120.     p4_brdcst_info.up = -1;    /* -1 means no one there */
  121.     p4_brdcst_info.left_cluster = -1;
  122.     p4_brdcst_info.right_cluster = -1;
  123.     p4_brdcst_info.left_slave = -1;
  124.     p4_brdcst_info.right_slave = -1;
  125.  
  126.     me = p4_get_my_id();
  127.  
  128.     /* Make list of cluster masters and find my master */
  129.     /* Ideally should probably use p4_get_cluster_masters here */
  130.  
  131.     n_master = 0;
  132.     previous_id = -1;
  133.     for (node = 0; node < p4_num_total_ids(); node++)
  134.     {
  135.     if (p4_global->proctable[node].group_id != previous_id)
  136.     {
  137.         master_list[n_master++] = node;
  138.         previous_id = p4_global->proctable[node].group_id;
  139.     }
  140.     if (node == me)
  141.         indx = n_master - 1;
  142.     }
  143.     if (indx < 0)
  144.     p4_error("init_p4_brdcst_info: my master indx bad", indx);
  145.     my_master = master_list[indx];
  146.  
  147.     /*
  148.     printf("me=%d, indx=%d, n_master=%d, my_master=%d, myclusterid=%d, list=[",
  149.        me, indx, n_master, my_master, p4_get_my_cluster_id()); 
  150.     for (node=0; node<n_master; node++) 
  151.     printf(" %d",master_list[node]); 
  152.     printf(" ]\n");
  153.     */
  154.  
  155.     if (me == my_master)
  156.     {
  157.     /* If cluster master assign cluster master tree */
  158.  
  159.     if ((2 * indx + 1) < n_master)
  160.         p4_brdcst_info.left_cluster = master_list[2 * indx + 1];
  161.  
  162.     if ((2 * indx + 2) < n_master)
  163.         p4_brdcst_info.right_cluster = master_list[2 * indx + 2];
  164.  
  165.     if (me)
  166.         p4_brdcst_info.up = master_list[(indx - 1) / 2];
  167.     }
  168.  
  169.     /* Now assign connections with own subtree */
  170.     p4_dprintfl(90, "brdcst_info: numclusids=%d\n", p4_num_cluster_ids());
  171.     node = 2 * p4_get_my_cluster_id() + 1;
  172.     if (node < p4_num_cluster_ids())
  173.     p4_brdcst_info.left_slave = node + my_master;
  174.  
  175.     node = 2 * p4_get_my_cluster_id() + 2;
  176.     if (node < p4_num_cluster_ids())
  177.     p4_brdcst_info.right_slave = node + my_master;
  178.  
  179.     if (me != my_master)
  180.     p4_brdcst_info.up = my_master + (p4_get_my_cluster_id() - 1) / 2;
  181.  
  182.     p4_dprintfl(90, "brdcst_info: me=%d up=%d clusters(%d, %d) slaves(%d,%d)\n",
  183.         me,
  184.         p4_brdcst_info.up,
  185.         p4_brdcst_info.left_cluster,
  186.         p4_brdcst_info.right_cluster,
  187.         p4_brdcst_info.left_slave,
  188.         p4_brdcst_info.right_slave);
  189.  
  190.     /* Sanity check */
  191.  
  192.     if (p4_brdcst_info.up != -1)
  193.     if (CHECKNODE(p4_brdcst_info.up))
  194.         p4_error("init_p4_brdcst_info: up node is invalid", p4_brdcst_info.up);
  195.     if (p4_brdcst_info.left_cluster != -1)
  196.     if (CHECKNODE(p4_brdcst_info.left_cluster))
  197.         p4_error("init_p4_brdcst_info: left_cluster node is invalid",
  198.              p4_brdcst_info.left_cluster);
  199.     if (p4_brdcst_info.right_cluster != -1)
  200.     if (CHECKNODE(p4_brdcst_info.right_cluster))
  201.         p4_error("init_p4_brdcst_info: right_cluster node is invalid",
  202.              p4_brdcst_info.right_cluster);
  203.     if (p4_brdcst_info.left_slave != -1)
  204.     if (CHECKNODE(p4_brdcst_info.left_slave))
  205.         p4_error("init_p4_brdcst_info: left_slave node is invalid",
  206.              p4_brdcst_info.left_slave);
  207.     if (p4_brdcst_info.right_slave != -1)
  208.     if (CHECKNODE(p4_brdcst_info.right_slave))
  209.         p4_error("init_p4_brdcst_info: right_slave node is invalid",
  210.              p4_brdcst_info.right_slave);
  211. }
  212.  
  213.  
  214. int p4_global_op(type, x, nelem, size, op, data_type)
  215. int type;
  216. char *x;
  217. int nelem;
  218. int size;
  219. int data_type;
  220. P4VOID(*op) ();
  221. /* see userman for more details */
  222. {
  223.     int me = p4_get_my_id();
  224.     int status = 0;
  225.     int zero = 0;
  226.     int msg_len;
  227.     char *msg;
  228.  
  229.     init_p4_brdcst_info();
  230.  
  231.     /* Accumulate up broadcast tree ... mess is due to return of soft errors */
  232.  
  233.     if (!status)
  234.     if (p4_brdcst_info.left_slave > 0)
  235.     {
  236.         msg = NULL;
  237.         status = p4_recv(&type, &p4_brdcst_info.left_slave, &msg, &msg_len);
  238.         if (!status)
  239.         {
  240.         op(x, msg, msg_len / size);
  241.         p4_msg_free(msg);
  242.         }
  243.     }
  244.     if (!status)
  245.     if (p4_brdcst_info.right_slave > 0)
  246.     {
  247.         msg = NULL;
  248.         status = p4_recv(&type, &p4_brdcst_info.right_slave, &msg, &msg_len);
  249.         if (!status)
  250.         {
  251.         op(x, msg, msg_len / size);
  252.         p4_msg_free(msg);
  253.         }
  254.     }
  255.     if (!status)
  256.     if (p4_brdcst_info.left_cluster > 0)
  257.     {
  258.         msg = NULL;
  259.         status = p4_recv(&type, &p4_brdcst_info.left_cluster, &msg, &msg_len);
  260.         if (!status)
  261.         {
  262.         op(x, msg, msg_len / size);
  263.         p4_msg_free(msg);
  264.         }
  265.     }
  266.     if (!status)
  267.     if (p4_brdcst_info.right_cluster > 0)
  268.     {
  269.         msg = NULL;
  270.         status = p4_recv(&type, &p4_brdcst_info.right_cluster, &msg, &msg_len);
  271.         if (!status)
  272.         {
  273.         op(x, msg, msg_len / size);
  274.         p4_msg_free(msg);
  275.         }
  276.     }
  277.  
  278.     if ((!status) && p4_get_my_id())
  279.     status = p4_sendx(type, p4_brdcst_info.up, x, nelem * size, data_type);
  280.  
  281.     /* Broadcast the result back */
  282.  
  283.     if (!status)
  284.     {
  285.     if (me == 0)
  286.         status = p4_broadcastx(type, x, nelem * size, data_type);
  287.     else
  288.     {
  289.         msg = NULL;
  290.         status = p4_recv(&type, &zero, &msg, &msg_len);
  291.         if (!status)
  292.         {
  293.         bcopy(msg, (char *) x, msg_len);
  294.         p4_msg_free(msg);
  295.         }
  296.     }
  297.     }
  298.  
  299.     if (status && !SOFTERR)
  300.     p4_error("p4_global_op failed, type=", type);
  301.  
  302.     return status;
  303. }
  304.  
  305. /* Standard operations on doubles */
  306.  
  307. P4VOID p4_dbl_sum_op(x, y, nelem)
  308. char *x, *y;
  309. int nelem;
  310. {
  311.     double *a = (double *) x;
  312.     double *b = (double *) y;
  313.  
  314.     while (nelem--)
  315.     *a++ += *b++;
  316. }
  317.  
  318. P4VOID p4_dbl_mult_op(x, y, nelem)
  319. char *x, *y;
  320. int nelem;
  321. {
  322.     double *a = (double *) x;
  323.     double *b = (double *) y;
  324.  
  325.     while (nelem--)
  326.     *a++ *= *b++;
  327. }
  328.  
  329. P4VOID p4_dbl_max_op(x, y, nelem)
  330. char *x, *y;
  331. int nelem;
  332. {
  333.     double *a = (double *) x;
  334.     double *b = (double *) y;
  335.  
  336.     while (nelem--)
  337.     {
  338.     *a = MAXVAL(*a, *b);
  339.     a++;
  340.     b++;
  341.     }
  342. }
  343.  
  344. P4VOID p4_dbl_min_op(x, y, nelem)
  345. char *x, *y;
  346. int nelem;
  347. {
  348.     double *a = (double *) x;
  349.     double *b = (double *) y;
  350.  
  351.     while (nelem--)
  352.     {
  353.     *a = MINVAL(*a, *b);
  354.     a++;
  355.     b++;
  356.     }
  357. }
  358.  
  359. P4VOID p4_dbl_absmax_op(x, y, nelem)
  360. char *x, *y;
  361. int nelem;
  362. {
  363.     double *a = (double *) x;
  364.     double *b = (double *) y;
  365.  
  366.     while (nelem--)
  367.     {
  368.     *a = MAXVAL(ABSVAL(*a), ABSVAL(*b));
  369.     a++;
  370.     b++;
  371.     }
  372. }
  373.  
  374. P4VOID p4_dbl_absmin_op(x, y, nelem)
  375. char *x, *y;
  376. int nelem;
  377. {
  378.     double *a = (double *) x;
  379.     double *b = (double *) y;
  380.  
  381.     while (nelem--)
  382.     {
  383.     *a = MINVAL(ABSVAL(*a), ABSVAL(*b));
  384.     a++;
  385.     b++;
  386.     }
  387. }
  388.  
  389. /* Standard operations on floats */
  390.  
  391. P4VOID p4_flt_sum_op(x, y, nelem)
  392. char *x, *y;
  393. int nelem;
  394. {
  395.     float *a = (float *) x;
  396.     float *b = (float *) y;
  397.  
  398.     while (nelem--)
  399.     *a++ += *b++;
  400. }
  401.  
  402. P4VOID p4_flt_mult_op(x, y, nelem)
  403. char *x, *y;
  404. int nelem;
  405. {
  406.     float *a = (float *) x;
  407.     float *b = (float *) y;
  408.  
  409.     while (nelem--)
  410.     *a++ *= *b++;
  411. }
  412.  
  413. P4VOID p4_flt_max_op(x, y, nelem)
  414. char *x, *y;
  415. int nelem;
  416. {
  417.     float *a = (float *) x;
  418.     float *b = (float *) y;
  419.  
  420.     while (nelem--)
  421.     {
  422.     *a = MAXVAL(*a, *b);
  423.     a++;
  424.     b++;
  425.     }
  426. }
  427.  
  428. P4VOID p4_flt_min_op(x, y, nelem)
  429. char *x, *y;
  430. int nelem;
  431. {
  432.     float *a = (float *) x;
  433.     float *b = (float *) y;
  434.  
  435.     while (nelem--)
  436.     {
  437.     *a = MINVAL(*a, *b);
  438.     a++;
  439.     b++;
  440.     }
  441. }
  442.  
  443. P4VOID p4_flt_absmax_op(x, y, nelem)
  444. char *x, *y;
  445. int nelem;
  446. {
  447.     float *a = (float *) x;
  448.     float *b = (float *) y;
  449.  
  450.     while (nelem--)
  451.     {
  452.     *a = MAXVAL(ABSVAL(*a), ABSVAL(*b));
  453.     a++;
  454.     b++;
  455.     }
  456. }
  457.  
  458. P4VOID p4_flt_absmin_op(x, y, nelem)
  459. char *x, *y;
  460. int nelem;
  461. {
  462.     float *a = (float *) x;
  463.     float *b = (float *) y;
  464.  
  465.     while (nelem--)
  466.     {
  467.     *a = MINVAL(ABSVAL(*a), ABSVAL(*b));
  468.     a++;
  469.     b++;
  470.     }
  471. }
  472.  
  473.  
  474. /* Standard operations on integers */
  475.  
  476. P4VOID p4_int_sum_op(x, y, nelem)
  477. char *x, *y;
  478. int nelem;
  479. {
  480.     int *a = (int *) x;
  481.     int *b = (int *) y;
  482.  
  483.     while (nelem--)
  484.     *a++ += *b++;
  485. }
  486.  
  487. P4VOID p4_int_mult_op(x, y, nelem)
  488. char *x, *y;
  489. int nelem;
  490. {
  491.     int *a = (int *) x;
  492.     int *b = (int *) y;
  493.  
  494.     while (nelem--)
  495.     *a++ *= *b++;
  496. }
  497.  
  498. P4VOID p4_int_max_op(x, y, nelem)
  499. char *x, *y;
  500. int nelem;
  501. {
  502.     int *a = (int *) x;
  503.     int *b = (int *) y;
  504.  
  505.     while (nelem--)
  506.     {
  507.     *a = MAXVAL(*a, *b);
  508.     a++;
  509.     b++;
  510.     }
  511. }
  512.  
  513. P4VOID p4_int_min_op(x, y, nelem)
  514. char *x, *y;
  515. int nelem;
  516. {
  517.     int *a = (int *) x;
  518.     int *b = (int *) y;
  519.  
  520.     while (nelem--)
  521.     {
  522.     *a = MINVAL(*a, *b);
  523.     a++;
  524.     b++;
  525.     }
  526. }
  527.  
  528. P4VOID p4_int_absmax_op(x, y, nelem)
  529. char *x, *y;
  530. int nelem;
  531. {
  532.     int *a = (int *) x;
  533.     int *b = (int *) y;
  534.  
  535.     while (nelem--)
  536.     {
  537.     *a = MAXVAL(ABSVAL(*a), ABSVAL(*b));
  538.     a++;
  539.     b++;
  540.     }
  541. }
  542.  
  543. P4VOID p4_int_absmin_op(x, y, nelem)
  544. char *x, *y;
  545. int nelem;
  546. {
  547.     int *a = (int *) x;
  548.     int *b = (int *) y;
  549.  
  550.     while (nelem--)
  551.     {
  552.     *a = MINVAL(ABSVAL(*a), ABSVAL(*b));
  553.     a++;
  554.     b++;
  555.     }
  556. }
  557.